// EffectSystem.cs

using System;
using UnityEngine;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = UnityEngine.Debug;

// =========================================================
// Buff Type & Data (定义)
// =========================================================

public enum BuffType
{
    Strength,       // 力量：修正伤害输出
    Dexterity,      // 敏捷：修正格挡输出
    Weak,           // 虚弱：修正伤害输入 (减伤)
    Vulnerable,      // 易伤：修正伤害输入 (增伤)
    Regeneration,    // 再生 - 每回合恢复生命
    Poison,         // 中毒：对目标造成持续伤害
}

[System.Serializable]
public class Buff
{
    public BuffType type;
    public int stacks;
    public bool isDisposable; // 是否在回合结束时自动移除一层 (如易伤/虚弱)
    // 可以添加其他属性，如 isDebuff, isStackable, duration 等
}

// =========================================================
// EffectSystem 核心模块
// =========================================================
public class EffectSystem : MonoBehaviour
{
    // === 事件定义 (Observer Pattern) ===
    // 用于通知 UI 和其他系统状态变化
    public static event Action<ITarget, int> OnDamageApplied;
    public static event Action<ITarget, int> OnBlockGained;
    public static event Action<ITarget, BuffType, int> OnBuffStacksChanged;
    

    // -----------------------------------------------------
    // 1. 伤害应用 ApplyDamage
    // -----------------------------------------------------
    public void ApplyDamage(ITarget source, ITarget target, int baseAmout)
    {
        int finalDamage = baseAmout;
        
        // 1. 来源修饰符：力量 (Strength)
        Buff strength = source.GetBuff(BuffType.Strength);
        if (strength != null)
        {
            finalDamage += strength.stacks; // 每层力量 +1 伤害
        }

        // 2. 目标修饰符：易伤 (Vulnerable)
        Buff vulnerable = target.GetBuff(BuffType.Vulnerable);
        if (vulnerable != null)
        {
            // 易伤：通常为受到伤害增加 50% (Slay the Spire 机制)
            // 注意：您可以根据您的设计文档修改 1.5f 这个数值
            finalDamage = (int)(finalDamage * 1.5f);
        }
        
        // 3. 目标修饰符：虚弱 (Weak)
        Buff weak = target.GetBuff(BuffType.Weak);
        if (weak != null)
        {
            // 虚弱：通常为受到伤害减少 25% (Slay the Spire 机制)
            finalDamage = (int)(finalDamage * 0.75f); 
        }

        // 4. 确保伤害至少为 0
        finalDamage = Math.Max(0, finalDamage);
        
        // --- 5. 格挡结算 ---
        int damageRemaining = finalDamage;
        
        if (target.Block > 0)
        {
            // 计算被格挡后剩余的伤害 (可能为 0)
            damageRemaining = Math.Max(0, finalDamage - target.Block);
            
            // 消耗格挡值
            target.Block = Math.Max(0, target.Block - finalDamage);

            // 通知 UI 格挡值变化
            Debug.Log($"[EffectSystem] 格挡结算: 伤害{finalDamage} -> 新格挡{target.Block}");
            OnBlockGained?.Invoke(target, target.Block);
        }
        
        // --- 6. 生命值扣除 ---
        target.currentHP -= damageRemaining;

        // --- 7. 抛出事件 ---
        // 通知 UI 伤害结算完成，显示飘字等
        OnDamageApplied?.Invoke(target, damageRemaining);
        
        // TODO: 考虑添加一个日志，以便在 Unity Console 中查看结果
        // Debug.Log($"Damage Applied: {damageRemaining}, HP Left: {target.currentHP}");
    }

    // -----------------------------------------------------
    // 2. 状态应用 ApplyBuff
    // -----------------------------------------------------
    public void ApplyBuff(ITarget target, BuffType type, int stacks, bool isDisposable)
    {
        // 1. 获取目标身上的 Buff
        Buff existingBuff = target.GetBuff(type);

        if (existingBuff != null)
        {
            // 2. 如果 Buff 存在，累加层数
            existingBuff.stacks += stacks;
        }
        else
        {
            // 3. 如果 Buff 不存在，添加新的 Buff
            target.AddBuff(new Buff { type = type, stacks = stacks ,isDisposable = isDisposable});
        }
        
        // 4. 抛出事件通知 UI
        // 确保 Buff 存在
        Buff currentBuff = target.GetBuff(type);
        if (currentBuff != null)
        {
            OnBuffStacksChanged?.Invoke(target, type, currentBuff.stacks);
        }
    }

    // TODO: 接下来需要实现 ApplyBlock、ApplyHeal、RemoveBuff 等方法

    // 示例：实现 ApplyBlock，它应该计算敏捷
    public void ApplyBlock(ITarget target, int baseAmount)
    {
        int finalBlock = baseAmount;

        // 计算敏捷 (Dexterity)：每层敏捷 +1 格挡
        Buff dexterity = target.GetBuff(BuffType.Dexterity);
        if (dexterity != null)
        {
            finalBlock += dexterity.stacks;
        }

        target.Block += finalBlock;

        // 通知 UI 格挡值变化
        Debug.Log($"[EffectSystem] ApplyBlock调用: 基础{baseAmount} -> 最终{finalBlock} -> {target.Block}");
        Debug.Log($"[EffectSystem] OnBlockGained事件触发: 目标={target.GetType().Name}, Block={target.Block}");

        // 检查是否有订阅者
        if (OnBlockGained == null)
        {
            Debug.LogWarning("[EffectSystem] OnBlockGained 事件没有订阅者！");
        }
        else
        {
            Debug.Log($"[EffectSystem] OnBlockGained 事件订阅者数量: {OnBlockGained.GetInvocationList().Length}");
        }
        OnBlockGained?.Invoke(target, target.Block);
        
    }
    /// <summary>
    /// 触发目标在回合开始时生效的 Buff 效果 (如中毒)
    /// </summary>
    public void TriggerAtTurnStart(ITarget target)
    {
        // 核心逻辑：遍历 Buffs，执行中毒、灼烧等效果
        
        // 1. 获取目标身上的所有 Buff (需要 ITarget 接口支持)
        List<Buff> activeBuffs = target.GetAllBuffs(); 
        
        if (activeBuffs == null || activeBuffs.Count == 0) return;

        // 2. 遍历并执行效果
        foreach (var buff in activeBuffs)
        {
            if (buff.type == BuffType.Poison)
            {
                // 毒药伤害：对目标造成等于层数的伤害
                // 注意：这里是毒药对目标自己造成伤害
                ApplyDamage(source: target, target: target, baseAmout: buff.stacks);
                
                // 毒药层数减少 1 (这是 Slay the Spire 的规则，需要与 DataManager 约定)
                buff.stacks -= 1; 
                Debug.Log($"[EffectSystem] {target.GetType().Name} 受到毒药伤害，毒药减少一层。");
            }
            // 再生效果
            if (buff.type == BuffType.Regeneration && buff.stacks > 0)
            {
                target.currentHP += buff.stacks;
                buff.stacks--; // 再生层数减少
                Debug.Log($"[EffectSystem] {target.GetType().Name} 再生效果获得回复，再生减少一层。");
            }
            // TODO: 添加其他回合开始 Buff (如每回合回复 HP 等)
        }
        
        // 3. 清理层数 <= 0 的 Buff
        target.RemoveExpiredBuffs(); // 假设 ITarget 提供了清理自身过期 Buff 的方法
    }

    /// <summary>
    /// 触发目标在回合结束时生效的 Buff 效果 (如虚弱/易伤的持续时间递减)
    /// </summary>
    public void TriggerAtTurnEnd(ITarget target)
    {
        // 核心逻辑：遍历 Buffs，减少易伤/虚弱等易逝 Buff 的层数
        
        List<Buff> activeBuffs = target.GetAllBuffs();
        if (activeBuffs == null || activeBuffs.Count == 0) return;

        // 1. 遍历并执行持续时间递减
        foreach (var buff in activeBuffs)
        {
            // 易逝 Buff 检查：
            if (buff.isDisposable && buff.stacks > 0)
            {
                buff.stacks -= 1; // 持续时间/层数递减
                Debug.Log($"[EffectSystem] {target.GetType().Name} Buff: {buff.type} 持续时间递减。");
            }
        }
        
        // 2. 清理层数 <= 0 的 Buff
        target.RemoveExpiredBuffs(); // 再次调用清理
    }
}